/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pe.gob.foncodes.ssa.web.servlet;

import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.util.*;
import javax.imageio.IIOImage;
import javax.imageio.ImageWriteParam;
import org.apache.log4j.Logger;
import javax.imageio.ImageWriter;
import pe.gob.foncodes.ssa.bs.common.util.Constante;

/**
 * @author Gregorovichz Carlos Rossi
 */
public class CaptchaServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    private int height = 0;
    private int width = 0;
    protected static Logger log = Logger.getLogger(CaptchaServlet.class);

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }
 
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response)
            throws IOException, ServletException {
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Max-Age", 0);
        try {
            Color textColor = Color.blue;
            Color circleColor = new Color(253, 212, 35);
            Font textFont = new Font("Arial", Font.PLAIN, 24);
            int charsToPrint = 6;
            width = 140;
            height = 40;
            int circlesToDraw = 4;
            float horizMargin = 20.0f;
            float imageQuality = 0.95f;
            double rotationRange = 0.7;
            BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
            g.setColor(Color.white);
            g.fillRect(0, 0, width, height);
            g.setColor(circleColor);
            for (int i = 0; i < circlesToDraw; i++) {
                int circleRadius = (int) (Math.random() * height / 2.0);
                int circleX = (int) (Math.random() * width - circleRadius);
                int circleY = (int) (Math.random() * height - circleRadius);
                g.drawOval(circleX, circleY, circleRadius * 2, circleRadius * 2);
            }
            g.setColor(textColor);
            g.setFont(textFont);
            FontMetrics fontMetrics = g.getFontMetrics();
            int maxAdvance = fontMetrics.getMaxAdvance();
            int fontHeight = fontMetrics.getHeight();
            char[] chars = Constante.ELEGIBLE_CHARS.toCharArray();
            float spaceForLetters = -horizMargin * 2 + width;
            float spacePerChar = spaceForLetters / (charsToPrint - 1.0f);
            StringBuilder finalString = new StringBuilder();
            for (int i = 0; i < charsToPrint; i++) {
                double randomValue = Math.random();
                int randomIndex = (int) Math.round(randomValue * (chars.length - 1));
                char characterToShow = chars[randomIndex];
                finalString.append(characterToShow);
                int charWidth = fontMetrics.charWidth(characterToShow);
                int charDim = Math.max(maxAdvance, fontHeight);
                int halfCharDim = (int) (charDim / 2);
                BufferedImage charImage = new BufferedImage(charDim, charDim, BufferedImage.TYPE_INT_ARGB);
                Graphics2D charGraphics = charImage.createGraphics();
                charGraphics.translate(halfCharDim, halfCharDim);
                double angle = (Math.random() - 0.5) * rotationRange;
                charGraphics.transform(AffineTransform.getRotateInstance(angle));
                charGraphics.translate(-halfCharDim, -halfCharDim);
                charGraphics.setColor(textColor);
                charGraphics.setFont(textFont);
                int charX = (int) (0.5 * charDim - 0.5 * charWidth);
                charGraphics.drawString("" + characterToShow, charX,
                        (int) ((charDim - fontMetrics.getAscent())
                        / 2 + fontMetrics.getAscent()));
                float x = horizMargin + spacePerChar * (i) - charDim / 2.0f;
                int y = (int) ((height - charDim) / 2);
                g.drawImage(charImage, (int) x, y, charDim, charDim, null, null);
                charGraphics.dispose();
            }
            Iterator iter = ImageIO.getImageWritersByFormatName("JPG");
            if (iter.hasNext()) {
                ImageWriter writer = (ImageWriter) iter.next();
                ImageWriteParam iwp = writer.getDefaultWriteParam();
                iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                iwp.setCompressionQuality(imageQuality);
                writer.setOutput(ImageIO.createImageOutputStream(response.getOutputStream()));
                IIOImage imageIO = new IIOImage(bufferedImage, null, null);
                writer.write(null, imageIO, iwp);
            } else {
                throw new RuntimeException("error al dibujar el servlet");
            }
            g.dispose();
            HttpSession session = req.getSession(true);
            session.setAttribute(Constante.CAPTCHA_KEY, finalString.toString());
        } catch (Exception err) {
            log.error(err.getMessage());
        }
    }
}
